package modules.rpt.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import luxing.common.controller.BaseController;
import luxing.exception.BusinessException;
import luxing.hibernate.CriteriaQuery;
import luxing.util.CriteriaQueryUtil;
import luxing.util.ValidatorUtil;
import luxing.web.model.DataGrid;
import luxing.web.model.Result;
import modules.arc.entity.Vehicle;
import modules.fin.entity.Expenses;
import modules.fin.entity.Outlay;
import modules.fin.entity.OutlaySum;
import modules.fin.service.ExpensesService;
import modules.fin.service.OutlayService;
import modules.sys.entity.Log;
import modules.sys.service.LogService;

/**
 * 
 * @author zzc
 *
 */
@Controller
@RequestMapping("/rptOutlayingController")
public class RptOutlayingController extends BaseController {

	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(RptOutlayingController.class);

	@Autowired
	private LogService logService;
	@Autowired
	private OutlayService outlayService;
	@Autowired
	private ExpensesService expensesService;

	/**
	 * 列表页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "index")
	public ModelAndView index(HttpServletRequest request) {
		List<Expenses> expensesList = expensesService.listByTypeAndStatus(Expenses.TYPE_OUTLAY, Expenses.STATUS_ENABLE);
		request.setAttribute("expensesList", expensesList);
		return new ModelAndView("modules/fin/outlay-list");
	}

	/**
	 * 列表数据
	 * 
	 * @param outlay
	 * @param request
	 * @param response
	 * @param dataGrid
	 */
	@RequestMapping(params = "list")
	public void list(Outlay outlay, HttpServletRequest request, HttpServletResponse response, DataGrid dataGrid) {
		try {
			CriteriaQuery cq = new CriteriaQuery(Outlay.class, dataGrid);
			CriteriaQueryUtil.assembling(cq, outlay, request.getParameterMap());
			// 费用类型
			String exs = request.getParameter("exs");
			if (StringUtils.isNotBlank(exs)) {
				cq.eq("expenses.id", exs);
			}
			cq.add();
			outlayService.listByPage(cq, true);
			dataGrid.setFooter("incomeAmount,discountAmount,settleAmount,vehicle.sn:合计");
			listView(response, dataGrid);
		} catch (Exception e) {
			logger.error("收车辆款查询失败", e);
			throw new BusinessException("收车辆款查询失败", e);
		}
	}

	/**
	 * 增加页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goAdd")
	public ModelAndView goAdd(HttpServletRequest req) {
		List<Expenses> expensesList = expensesService.listByTypeAndStatus(Expenses.TYPE_OUTLAY, Expenses.STATUS_ENABLE);
		if (CollectionUtils.isNotEmpty(expensesList)) {
			req.setAttribute("outlayAmount", expensesList.get(0).getAmount());
		}
		req.setAttribute("expensesList", expensesList);
		return new ModelAndView("modules/fin/outlay-add");
	}

	/**
	 * 修改页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goUpdate")
	public ModelAndView goUpdate(Outlay outlay, HttpServletRequest req) {
		if (StringUtils.isNotBlank(outlay.getId())) {
			outlay = outlayService.get(Outlay.class, outlay.getId());
			req.setAttribute("outlayPage", outlay);
		}
		List<Expenses> expensesList = expensesService.listByTypeAndStatus(Expenses.TYPE_OUTLAY, Expenses.STATUS_ENABLE);
		req.setAttribute("expensesList", expensesList);
		return new ModelAndView("modules/fin/outlay-update");
	}

	/**
	 * 查看页面
	 * 
	 * @param insurance
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "goDetail")
	public ModelAndView goDetail(Outlay outlay, HttpServletRequest req) {
		if (StringUtils.isNotBlank(outlay.getId())) {
			outlay = outlayService.get(Outlay.class, outlay.getId());
			req.setAttribute("outlayPage", outlay);
		}
		List<Expenses> expensesList = expensesService.listByTypeAndStatus(Expenses.TYPE_OUTLAY, Expenses.STATUS_ENABLE);
		req.setAttribute("expensesList", expensesList);
		return new ModelAndView("modules/fin/outlay-detail");
	}

	/**
	 * 责任人核销页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goOwnerSettle")
	public ModelAndView goOwnerSettle(HttpServletRequest req) {
		return new ModelAndView("modules/fin/outlayOwner-settle");
	}

	/**
	 * 车辆核销页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goVehicleSettle")
	public ModelAndView goVehicleSettle(Outlay outlay, HttpServletRequest req) {
		if (StringUtils.isNotBlank(outlay.getId())) {
			outlay = outlayService.get(Outlay.class, outlay.getId());
			req.setAttribute("outlayPage", outlay);
		}
		return new ModelAndView("modules/fin/outlayVehicle-settle");
	}

	/**
	 * 费用tab
	 * 
	 * @return
	 */
	@RequestMapping(params = "expensesTab")
	public ModelAndView expensesList(HttpServletRequest req) {
		List<Expenses> expensesList = expensesService.listByTypeAndStatus(Expenses.TYPE_OUTLAY, Expenses.STATUS_ENABLE);
		if (CollectionUtils.isNotEmpty(expensesList)) {
			req.setAttribute("outlayAmount", expensesList.get(0).getAmount());
		}
		req.setAttribute("expensesList", expensesList);
		return new ModelAndView("modules/fin/outlayExpenses-tab");
	}

	/**
	 * 责任人核销明细
	 * 
	 * @return
	 */
	@RequestMapping(params = "ownerSettleTab")
	public ModelAndView ownerSettleTab(HttpServletRequest req) {
		String ownerId = req.getParameter("ownerId");
		List<Outlay> outlayList = outlayService.listByOwnerAndStatus(ownerId, Outlay.STATUS_NO);
		BigDecimal totalOutlayAmount = new BigDecimal(0);
		BigDecimal totalSettleAmount = new BigDecimal(0);
		for (Outlay outlay : outlayList) {
			totalOutlayAmount = totalOutlayAmount.add(outlay.getOutlayAmount());
			totalSettleAmount = totalOutlayAmount;
		}
		req.setAttribute("totalOutlayAmount", totalOutlayAmount);
		req.setAttribute("totalSettleAmount", totalSettleAmount);
		req.setAttribute("outlayList", outlayList);
		return new ModelAndView("modules/fin/outlayOwnerSettle-tab");
	}

	/**
	 * 车辆核销明细
	 * 
	 * @return
	 */
	@RequestMapping(params = "vehicleSettleTab")
	public ModelAndView vehicleSettleTab(HttpServletRequest req) {
		String vehicleId = req.getParameter("vehicleId");
		List<Outlay> outlayList = outlayService.listByVehicleAndStatus(vehicleId, Outlay.STATUS_NO);
		BigDecimal totalOutlayAmount = new BigDecimal(0);
		BigDecimal totalSettleAmount = new BigDecimal(0);
		for (Outlay outlay : outlayList) {
			totalOutlayAmount = totalOutlayAmount.add(outlay.getOutlayAmount());
			totalSettleAmount = totalOutlayAmount;
		}
		req.setAttribute("totalOutlayAmount", totalOutlayAmount);
		req.setAttribute("totalSettleAmount", totalSettleAmount);
		req.setAttribute("outlayList", outlayList);
		return new ModelAndView("modules/fin/outlayVehicleSettle-tab");
	}

	/**
	 * 新增
	 * 
	 * @param income
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "doAdd")
	@ResponseBody
	public Result doAdd(Outlay outlay, HttpServletRequest request) {
		String msg = null;
		try {
			String vehicleId = request.getParameter("vehicleId");
			if (CollectionUtils.isNotEmpty(outlay.getOutlayList())) {
				List<Outlay> outlayList = new ArrayList<Outlay>();
				for (Outlay entity : outlay.getOutlayList()) {
					for (String id : vehicleId.split(",")) {
						Outlay outlayEntity = new Outlay();
						outlayEntity.setExpenses(entity.getExpenses());
						outlayEntity.setOutlayAmount(entity.getOutlayAmount());
						outlayEntity.setStatus(Outlay.STATUS_NO);
						Vehicle vehicle = new Vehicle();
						vehicle.setId(id);
						outlayEntity.setVehicle(vehicle);
						outlayEntity.setSettleAmount(new BigDecimal(0));
						outlayEntity.setRemarks(entity.getRemarks());
						outlayList.add(outlayEntity);
					}
				}
				outlayService.batchSave(outlayList);
			}
			msg = "付款登记成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_ADD);
		} catch (Exception e) {
			msg = "付款登记失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 核销
	 * 
	 * @param outlaySum
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "doSettle")
	@ResponseBody
	public Result doSettle(OutlaySum outlaySum, HttpServletRequest request) {
		String msg = null;
		try {
			if (CollectionUtils.isNotEmpty(outlaySum.getOutlayList())) {
				// 编号
				String sn = outlayService.getSn();
				outlaySum.setSn(sn);
				// 状态
				outlaySum.setStatus(OutlaySum.STATUS_ENABLE);
				// 核销金额
				BigDecimal totalSettleAmount = new BigDecimal(0);
				Iterator<Outlay> iterator = outlaySum.getOutlayList().iterator();
				while (iterator.hasNext()) {
					Outlay outlay = iterator.next();
					if (StringUtils.equals(outlay.getStatus(), Outlay.STATUS_YES)
							&& outlay.getSettleAmount().compareTo(outlay.getOutlayAmount()) == 0) {
						totalSettleAmount = totalSettleAmount.add(outlay.getSettleAmount());
					} else {
						iterator.remove();
					}
				}
				outlaySum.setAmount(totalSettleAmount);
				// bean校验
				msg = ValidatorUtil.validate(outlaySum);
				if (StringUtils.isNotBlank(msg)) {
					return Result.error(msg);
				}
				outlayService.settle(outlaySum);
				msg = "责任人\"" + outlaySum.getOwner().getName() + "\"付款核销成功";
				logger.info(msg);
				logService.addLogInfo(msg, Log.OPERATE_ADD);
			}
		} catch (Exception e) {
			msg = "责任人\"" + outlaySum.getOwner().getName() + "\"付款核销失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 修改
	 * 
	 * @param outlay
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "doUpdate")
	@ResponseBody
	public Result doUpdate(Outlay outlay, HttpServletRequest request) {
		String msg = null;
		try {
			// bean校验
			msg = ValidatorUtil.validate(outlay);
			if (StringUtils.isNotBlank(msg)) {
				return Result.error(msg);
			}
			outlayService.saveOrUpdate(outlay);
			msg = "车辆\"" + outlay.getVehicle().getPlateNumber() + "\"付款修改成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_UPDATE);
		} catch (Exception e) {
			msg = "车辆\"" + outlay.getVehicle().getPlateNumber() + "\"付款修改失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 删除
	 * 
	 * @return
	 */
	@RequestMapping(params = "doDel")
	@ResponseBody
	public Result doDel(Outlay outlay, HttpServletRequest request) {
		String msg = null;
		try {
			outlay = outlayService.get(Outlay.class, outlay.getId());
			outlayService.delete(outlay);
			msg = "车辆\"" + outlay.getVehicle().getPlateNumber() + "\"付款删除成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_DEL);
		} catch (Exception e) {
			msg = "车辆\"" + outlay.getVehicle().getPlateNumber() + "\"付款删除失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 费用change
	 * 
	 * @param req
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(params = "expensesChange")
	@ResponseBody
	public Result expensesChange(HttpServletRequest req) {
		Result result = new Result();
		Map<String, Object> attributes = new HashMap<String, Object>();
		String expensesId = req.getParameter("expensesId");
		Expenses expenses = expensesService.get(Expenses.class, expensesId);
		attributes.put("outlayAmount", expenses.getAmount());
		result.setAttributes(attributes);
		return result;
	}

}
